home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Info-Mac 3
/
Info_Mac_1994-01.iso
/
Development
/
Source
/
Bob 1.5 Source
/
Bobfcn.c
< prev
next >
Wrap
Text File
|
1991-10-12
|
6KB
|
291 lines
/* bobfcn.c - built-in classes and functions */
/*
Copyright (c) 1991, by David Michael Betz
All rights reserved
*/
#include "bob.h"
/* argument check macros */
#define argcount(n,cnt) { if ((n) != (cnt)) wrongcnt(n,cnt); }
/* stdio dispatch table */
IODISPATCH fileio = {
fclose,
fgetc,
fputc,
fputs
};
/* external variables */
extern VALUE symbols;
/* forward declarations */
#ifdef __STDC__
static int xtypeof(int argc);
static int xgc(int argc);
static int xnewvector(int argc);
static int xnewstring(int argc);
static int xsizeof(int argc);
static int xfopen(int argc);
static int xfclose(int argc);
static int xgetc(int argc);
static int xputc(int argc);
static int xprint(int argc);
static int xgetarg(int argc);
static int xsystem(int argc);
#else
int xtypeof(),xgc();
int xnewvector(),xnewstring(),xsizeof(),xprint(),xgetarg(),xsystem();
int xfopen(),xfclose(),xgetc(),xputc();
#endif
/* init_functions - initialize the internal functions */
void init_functions()
{
add_function("typeof",xtypeof);
add_function("gc",xgc);
add_function("newvector",xnewvector);
add_function("newstring",xnewstring);
add_function("sizeof",xsizeof);
add_function("fopen",xfopen);
add_function("fclose",xfclose);
add_function("getc",xgetc);
add_function("putc",xputc);
add_function("print",xprint);
add_function("getarg",xgetarg);
add_function("system",xsystem);
}
/* add_function - add a built-in function */
void add_function(name,fcn)
char *name; int (*fcn)();
{
DICT_ENTRY *sym;
sym = addentry(&symbols,name,ST_SFUNCTION);
set_code(&sym->de_value,fcn);
}
/* xtypeof - get the data type of a value */
static int xtypeof(argc)
int argc;
{
argcount(argc,1);
set_integer(&sp[1],sp->v_type);
++sp;
}
/* xgc - invoke the garbage collector */
static int xgc(argc)
int argc;
{
argcount(argc,0);
gc();
set_nil(sp);
}
/* xnewvector - allocate a new vector */
static int xnewvector(argc)
int argc;
{
int size;
argcount(argc,1);
chktype(0,DT_INTEGER);
size = sp->v.v_integer;
set_vector(&sp[1],newvector(size));
++sp;
}
/* xnewstring - allocate a new string */
static int xnewstring(argc)
int argc;
{
int size;
argcount(argc,1);
chktype(0,DT_INTEGER);
size = sp->v.v_integer;
set_string(&sp[1],newstring(size));
++sp;
}
/* xsizeof - get the size of a vector or string */
static int xsizeof(argc)
int argc;
{
argcount(argc,1);
switch (sp->v_type) {
case DT_VECTOR:
set_integer(&sp[1],sp->v.v_vector->vec_size);
break;
case DT_STRING:
set_integer(&sp[1],sp->v.v_string->str_size);
break;
default:
break;
}
++sp;
}
/* xfopen - open a file */
static int xfopen(argc)
int argc;
{
char name[50],mode[10];
FILE *fp;
argcount(argc,2);
chktype(0,DT_STRING);
chktype(1,DT_STRING);
getcstring(name,sizeof(name),&sp[1]);
getcstring(mode,sizeof(mode),&sp[0]);
if ((fp = fopen(name,mode)) == NULL)
set_nil(&sp[2]);
else
set_iostream(&sp[2],newiostream(&fileio,fp));
sp += 2;
}
/* xfclose - close a file */
static int xfclose(argc)
int argc;
{
argcount(argc,1);
chktype(0,DT_IOSTREAM);
set_integer(&sp[1],iosclose(&sp[0]));
++sp;
}
/* xgetc - get a character from a file */
static int xgetc(argc)
int argc;
{
argcount(argc,1);
chktype(0,DT_IOSTREAM);
set_integer(&sp[1],iosgetc(&sp[0]));
++sp;
}
/* xputc - output a character to a file */
static int xputc(argc)
int argc;
{
argcount(argc,2);
chktype(0,DT_IOSTREAM);
chktype(1,DT_INTEGER);
set_integer(&sp[2],iosputc((int)sp[1].v.v_integer,&sp[0]));
sp += 2;
}
/* xprint - generic print function */
static int xprint(argc)
int argc;
{
extern VALUE stdout_iostream;
int n;
for (n = argc; --n >= 0; )
print1(&stdout_iostream,FALSE,&sp[n]);
sp += argc;
set_nil(sp);
}
/* print1 - print one value */
print1(ios,qflag,val)
VALUE *ios; int qflag; VALUE *val;
{
char name[TKNSIZE+1],buf[200],*p;
VALUE *class;
int len;
switch (val->v_type) {
case DT_NIL:
iosputs("nil",ios);
break;
case DT_CLASS:
getcstring(name,sizeof(name),clgetname(val));
sprintf(buf,"#<Class-%s>",name);
iosputs(buf,ios);
break;
case DT_OBJECT:
sprintf(buf,"#<Object-%lx>",objaddr(val));
iosputs(buf,ios);
break;
case DT_VECTOR:
sprintf(buf,"#<Vector-%lx>",vecaddr(val));
iosputs(buf,ios);
break;
case DT_INTEGER:
sprintf(buf,"%ld",val->v.v_integer);
iosputs(buf,ios);
break;
case DT_STRING:
if (qflag) iosputc('"',ios);
p = strgetdata(val);
len = strgetsize(val);
while (--len >= 0)
iosputc(*p++,ios);
if (qflag) iosputc('"',ios);
break;
case DT_BYTECODE:
sprintf(buf,"#<Bytecode-%lx>",vecaddr(val));
iosputs(buf,ios);
break;
case DT_CODE:
sprintf(buf,"#<Code-%lx>",val->v.v_code);
iosputs(buf,ios);
break;
case DT_VAR:
class = digetclass(degetdictionary(val));
if (!isnil(class)) {
getcstring(name,sizeof(name),clgetname(class));
sprintf(buf,"%s::",name);
iosputs(buf,ios);
}
getcstring(name,sizeof(name),degetkey(val));
iosputs(name,ios);
break;
case DT_IOSTREAM:
sprintf(buf,"#<Stream-%lx>",val->v.v_iostream);
iosputs(buf,ios);
break;
default:
error("Undefined type: %d",valtype(val));
}
}
/* xgetarg - get an argument from the argument list */
static int xgetarg(argc)
int argc;
{
extern char **bobargv;
extern int bobargc;
int i;
argcount(argc,1);
chktype(0,DT_INTEGER);
i = sp[0].v.v_integer;
if (i >= 0 && i < bobargc)
set_string(&sp[1],makestring(bobargv[i]));
else
set_nil(&sp[1]);
++sp;
}
/* xsystem - execute a system command */
static int xsystem(argc)
int argc;
{
char cmd[133];
argcount(argc,1);
chktype(0,DT_STRING);
getcstring(cmd,sizeof(cmd),&sp[0]);
set_integer(&sp[1],system(cmd));
++sp;
}
/* wrongcnt - report wrong number of arguments */
void wrongcnt(n,cnt)
int n,cnt;
{
if (n < cnt)
error("Too many arguments");
else if (n > cnt)
error("Too few arguments");
}